/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年11月17日         Root.Lu
 */

package com.coocaa.x.service.litepm;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageParser;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;

import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.LiteHandlerThread;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.framework.utils.PMUtils;
import com.coocaa.x.framework.utils.PMUtils.PackageMoveLocation;
import com.coocaa.x.framework.utils.ShellUtils;
import com.coocaa.x.framework.utils.ShellUtils.CommandResult;
import com.coocaa.x.framework.utils.SystemUtils;
import com.coocaa.x.service.R;
import com.coocaa.x.service.XServiceManager;
import com.coocaa.x.service.litepm.PackageRunnable.PackageInstallerChecker;
import com.coocaa.x.service.litepm.data.AppInfo;
import com.coocaa.x.service.litepm.data.InstallParams;
import com.coocaa.x.service.litepm.data.MActivityInfo;
import com.skyworth.framework.skysdk.android.SdCardChecker;
import com.skyworth.framework.skysdk.android.SkySystemUtil;
import com.skyworth.framework.skysdk.ipc.SkyStartActivity;
import com.skyworth.framework.skysdk.logger.Logger;
import com.skyworth.logsdk.appstore.LogAPIForAppStore;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class PkgManager {
    private static final String TAG = "PkgManager";
    private static PkgManager instance = null;

    public static synchronized void create(Context context) {
        if (instance == null)
            instance = new PkgManager(context);
    }

    public static PkgManager getInstance() {
        return instance;
    }

    public interface AppClearCacheListener {
        void onPackageCacheClear(String packageName, boolean success);
    }

    public interface AppMoveListener {
        public void onPackageMoved(String pname, PackageMoveLocation location, boolean success);
    }

    public interface AppInstallListener {
        void onInstallStart(String apkfile, AppInfo appInfo, InstallParams params);

        void onInstallEnd(String apkfile, AppInfo appInfo, int result, String extra, InstallParams params);
    }

    public interface AppUnInstallListener {
        void onUninstallStart(AppInfo appInfo);

        void onUninstallEnd(AppInfo appInfo, int result, String extra);
    }

    public interface SpeedUpListener {
        void onSpeedUpStart(int configDelay, long free, long total);

        void onSpeedUpReallyKillEnd(long free, long total);

        void onSpeedUpEnd();
    }

    private abstract class InstallApkRunnable extends PackageRunnable {
        protected String apkfile = null;
        protected InstallParams params = null;

        public InstallApkRunnable(String apkfile, InstallParams params) {
            this.apkfile = apkfile;
            this.params = params;
        }

        public final String getApkfile() {
            return apkfile;
        }
    }

    private class InstallSilentRunnable extends InstallApkRunnable {
        public InstallSilentRunnable(String apkfile, InstallParams params) {
            super(apkfile, params);
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (!new File(apkfile).exists())
                return;
            try {
                LogUtils.d("slient_install", " chmod 777 " + apkfile);
                Runtime.getRuntime().exec("chmod 777 " + apkfile);
            } catch (Exception e) {
                e.printStackTrace();
            }
            AppInfo appinfo = getAPKInfo(apkfile);
            if (appinfo == null) {
                if (mInstallListener != null) {
                    mInstallListener.onInstallStart(apkfile, null, params);
                    mInstallListener.onInstallEnd(apkfile, null, PM_ERROR,
                            "INSTALL_FAILED_INVALID_APK", params);
                    LogAPIForAppStore.reportError("INSTALL_FAILED_INVALID_APK");
                }
            } else {
                int preferlocation = getInstallLocation(apkfile);
                LogUtils.d("install", "preferlocation:" + preferlocation);
                addRunningPackage(appinfo.pkgName);
                mInstallListener.onInstallStart(apkfile, appinfo, params);
                switch (preferlocation) {
                    case INSTALL_LOCATION_AUTO:
//                        if (SdCardChecker.isSDCardAvaiable()) {
//                            String arg = " -s ";
//                            if (needInstallSystem(apkfile)) {
//                                arg = "";
//                            }
//                            StringBuilder command = new StringBuilder().append("pm install -r " + arg).append(
//                                    apkfile);
//                            LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO silent install  cmd:" + command);
//                            CommandResult commandResult = ShellUtils
//                                    .execCommand(command.toString(), true, true);
//                            if (commandResult.successMsg != null
//                                    && (commandResult.successMsg.contains("Success") || commandResult.successMsg
//                                    .contains("success"))) {
//                                if (mInstallListener != null)
//                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
//                                            String.valueOf("Success"), params);
//                                LogAPIForAppStore
//                                        .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
//                                break;
//                            }
//                            if (arg.equals("")) {
//                                if (mInstallListener != null) {
//                                    LogUtils.d("slient_install", "arg is   INSTALL_LOCATION_AUTO Silent Install failed  for:" + commandResult.errorMsg);
//                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                            commandResult.errorMsg, params);
//                                }
//                                break;
//                            }
//                        }
//                        StringBuilder command0 = new StringBuilder().append("pm install -r ").append(
//                                apkfile);
//                        LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO silent install  cmd:" + command0);
//                        CommandResult commandResult0 = ShellUtils
//                                .execCommand(command0.toString(), true, true);
//                        if (commandResult0.successMsg != null
//                                && (commandResult0.successMsg.contains("Success") || commandResult0.successMsg
//                                .contains("success"))) {
//                            if (mInstallListener != null)
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
//                                        String.valueOf("Success"), params);
//                            LogAPIForAppStore
//                                    .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
//                        } else {
//                            if (mInstallListener != null) {
//                                LogUtils.d("slient_install", "INSTALL_LOCATION_AUTO Silent Install failed  for:" + commandResult0.errorMsg);
//                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
//                                        commandResult0.errorMsg, params);
//                            }
//                        }
//                        break;
                    case INSTALL_LOCATION_INTERNAL_ONLY:
                        StringBuilder command1 = new StringBuilder().append("pm install -r ").append(
                                apkfile);
                        LogUtils.d("slient_install", "INSTALL_LOCATION_INTERNAL_ONLY silent install  cmd:" + command1);
                        CommandResult commandResult1 = ShellUtils
                                .execCommand(command1.toString(), true, true);
                        if (commandResult1.successMsg != null
                                && (commandResult1.successMsg.contains("Success") || commandResult1.successMsg
                                .contains("success"))) {
                            if (mInstallListener != null)
                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
                                        String.valueOf("Success"), params);
                            LogAPIForAppStore
                                    .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                        } else {
                            if (mInstallListener != null) {
                                LogUtils.d("slient_install", "INSTALL_LOCATION_INTERNAL_ONLY Silent Install failed  for:" + commandResult1.errorMsg);
                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
                                        commandResult1.errorMsg, params);
                            }
                        }
                        break;
                    case INSTALL_LOCATION_PREFER_EXTERNAL:
                        if (SdCardChecker.isSDCardAvaiable()) {
                            String arg = " -s ";
                            if (needInstallSystem(apkfile)) {
                                if (mInstallListener != null) {
                                    LogUtils.d("slient_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install failed  for:  system apk  can not install to sdcard!");
                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
                                            "systemuid", params);
                                }
                                break;
                            }
                            StringBuilder command2 = new StringBuilder().append("pm install -r " + arg).append(
                                    apkfile);
                            LogUtils.d("slient_install", "INSTALL_LOCATION_PREFER_EXTERNAL silent install  cmd:" + command2);
                            CommandResult commandResult2 = ShellUtils
                                    .execCommand(command2.toString(), true, true);
                            if (commandResult2.successMsg != null
                                    && (commandResult2.successMsg.contains("Success") || commandResult2.successMsg
                                    .contains("success"))) {
                                if (mInstallListener != null)
                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_SUCCESSS,
                                            String.valueOf("Success"), params);
                                LogAPIForAppStore
                                        .appStatusNew(-1, appinfo.pkgName, appinfo.appName, "安装成功", "");
                            } else {
                                if (mInstallListener != null) {
                                    LogUtils.d("slient_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install failed  for:" + commandResult2.errorMsg);
                                    mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
                                            commandResult2.errorMsg, params);
                                }
                            }
                        } else {
                            if (mInstallListener != null) {
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                LogUtils.d("slient_install", "INSTALL_LOCATION_PREFER_EXTERNAL Silent Install failed...nosdcard..");
                                mInstallListener.onInstallEnd(apkfile, appinfo, PM_ERROR,
                                        "nosdcard", params);
                            }
                        }
                        break;
                    default:
                        break;
                }

                removeRunningPackage(appinfo.pkgName);
            }
        }
    }

    private class InstallUnsilentRunnable extends InstallApkRunnable implements
            PackageInstallerChecker {
        private int installer = 0;
        private boolean SP = false;

        public InstallUnsilentRunnable(String apkfile, InstallParams params) {
            super(apkfile, params);
        }

        public InstallUnsilentRunnable(String apkfile, boolean SP, InstallParams params) {
            super(apkfile, params);
            this.SP = SP;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (!new File(apkfile).exists())
                return;
            addChecker(this);
            try {
                Runtime.getRuntime().exec("chmod 777 " + apkfile);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            AppInfo appinfo = getAPKInfo(apkfile);
            if (appinfo != null) {
                addRunningPackage(appinfo.pkgName);
                if (mInstallListener != null)
                    mInstallListener.onInstallStart(apkfile, appinfo, params);
            }
            Uri uri = Uri.fromFile(new File(apkfile));
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (!SP)
                intent.putExtra("SKYWORTH_HIDE_FLAG_PACKAGENAME", mContext.getPackageName());

            int preferlocation = getInstallLocation(apkfile);
            LogUtils.d("HHHH", "preferlocation:" + preferlocation);
            switch (preferlocation) {
                case INSTALL_LOCATION_INTERNAL_ONLY:
                    intent.putExtra("APP_INSTALL_LOCATION", 1);
                    break;
                case INSTALL_LOCATION_PREFER_EXTERNAL:
                case INSTALL_LOCATION_AUTO:
                case INSTALL_LOCATION_UNSPECIFIED:
                    if (SdCardChecker.isSDCardAvaiable()) {
                        intent.putExtra("APP_INSTALL_LOCATION", 2);
                    } else {
                        intent.putExtra("APP_INSTALL_LOCATION", 0);
                    }
                    break;
            }
            mContext.startActivity(intent);
            synchronized (this) {
                try {
                    if (installer != 2)
                        wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            removeChecker(this);
            if (appinfo != null)
                removeRunningPackage(appinfo.pkgName);
            if (mInstallListener != null) {
                try {
                    boolean isInstalled = isAppInstalled(appinfo.pkgName);
                    mInstallListener.onInstallEnd(apkfile, appinfo,
                            isInstalled ? PM_SUCCESSS : PM_ERROR, String.valueOf("Success"), params);
                    // if (isInstalled)
                    // BigDataLog.log4InstallSuccess(appinfo.pkgName, appinfo.appName,
                    // appinfo.versionName);
                } catch (Exception e) {
                    e.printStackTrace();
                    mInstallListener.onInstallEnd(apkfile, null, PM_ERROR, "unknown error", params);
                }
            }
        }

        @Override
        public void onPackageInstallerAppear() {
            // TODO Auto-generated method stub
            synchronized (this) {
                LogUtils.i(TAG, "onPackageInstallerAppear");
                installer = 1;
            }
        }

        @Override
        public void onPackageInstallerDisappear() {
            // TODO Auto-generated method stub
            synchronized (this) {
                LogUtils.i(TAG, "onPackageInstallerDisappear");
                installer = 2;
                notify();
            }
        }
    }

    private class UninstallSilentRunnable extends PackageRunnable {
        private String pkgname = null;

        public UninstallSilentRunnable(String pkgname) {
            this.pkgname = pkgname;
        }

        @Override
        public void run() {
            AppInfo appInfo = getAppInfoFromLocal(pkgname);
            mUnInstallListener.onUninstallStart(appInfo);
            String command = "pm uninstall " + pkgname;
            Process process = null;
            try {
                 process = Runtime.getRuntime().exec(command);
                process.waitFor();
                process.getOutputStream().toString();
                if (mUnInstallListener != null) {
                    if (isAppInstalled(pkgname))
                        mUnInstallListener.onUninstallEnd(appInfo, PM_ERROR, "");
                    else {
//                        LogAPIForAppStore.appStatusNew(-1, pkgname, appName, "卸载成功", "");
                        mUnInstallListener.onUninstallEnd(appInfo, PM_SUCCESSS, "");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                mUnInstallListener.onUninstallEnd(appInfo, PM_ERROR, e.toString());
            }finally{
                if(process!=null){
                    process.destroy();
                }
            }
        }
    }

    private class UninstallUnsilentRunnable extends PackageRunnable implements
            PackageInstallerChecker {
        private String pkgname = null;
        private int installer = 0;

        public UninstallUnsilentRunnable(String pkgname) {
            this.pkgname = pkgname;
        }

        @Override
        public void run() {
            AppInfo appInfo = getAppInfoFromLocal(pkgname);
            mUnInstallListener.onUninstallStart(appInfo);
            addChecker(this);
            Uri packageURI = Uri.parse("package:" + pkgname);
            Intent intent = new Intent(Intent.ACTION_DELETE, packageURI);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent);
            synchronized (this) {
                try {
                    if (installer != 2)
                        wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            removeChecker(this);
            boolean isInstalled = isAppInstalled(pkgname);
            mUnInstallListener.onUninstallEnd(appInfo, !isInstalled ? PM_SUCCESSS : PM_ERROR, "");
//            if (!isInstalled)
//                LogAPIForAppStore.appStatusNew(-1, pkgname, appName, "卸载成功", "");
        }

        @Override
        public void onPackageInstallerAppear() {
            // TODO Auto-generated method stub
            synchronized (this) {
                LogUtils.i(TAG, "onPackageInstallerAppear");
                installer = 1;
            }
        }

        @Override
        public void onPackageInstallerDisappear() {
            // TODO Auto-generated method stub
            synchronized (this) {
                LogUtils.i(TAG, "onPackageInstallerDisappear");
                installer = 2;
                notify();
            }
        }
    }

    public static final int INSTALL_LOCATION_UNSPECIFIED = -1;
    public static final int INSTALL_LOCATION_AUTO = 0;
    public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1;
    public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;

    public static final int PM_SUCCESSS = 0;
    public static final int PM_ERROR = -1;

    private Context mContext = null;
    private LiteHandlerThread ht = null;
    private AppInstallListener mInstallListener = null;
    private AppUnInstallListener mUnInstallListener = null;
    private SpeedUpListener speedUpListener = null;
    private Thread speedUpThread = null;

    private PkgManager(Context c) {
        mContext = c;
        PackageRunnable.setContext(mContext);
        ht = new LiteHandlerThread("安装卸载");
        ht.start();
    }

    public void setInstallListener(AppInstallListener l) {
        mInstallListener = l;
    }

    public void setunInstallListener(AppUnInstallListener l) {
        mUnInstallListener = l;
    }

    public synchronized void install(String apkfile, boolean silent, InstallParams params) {
        if (apkfile == null)
            return;
        List<Runnable> rs = ht.getRunnableList();
        for (Runnable r : rs) {
            if (InstallApkRunnable.class.isInstance(r)) {
                InstallApkRunnable ir = (InstallApkRunnable) r;
                if (ir.getApkfile() != null && ir.getApkfile().equals(apkfile))
                    return;
            }
        }
        if (!new File(apkfile).exists())
            return;
        if (silent)
            ht.post(new InstallSilentRunnable(apkfile, params));
        else
            ht.post(new InstallUnsilentRunnable(apkfile, params));
    }

    public synchronized void installWithSP(String apkfile, InstallParams params) {
        if (apkfile == null)
            return;
        List<Runnable> rs = ht.getRunnableList();
        for (Runnable r : rs) {
            if (InstallApkRunnable.class.isInstance(r)) {
                InstallApkRunnable ir = (InstallApkRunnable) r;
                if (ir.getApkfile() != null && ir.getApkfile().equals(apkfile))
                    return;
            }
        }
        if (!new File(apkfile).exists())
            return;
        ht.post(new InstallUnsilentRunnable(apkfile, true, params));
    }

    public void uninstall(String pkgname, boolean silent) {
        // check tc is lowversion!!!
        if (silent)
            ht.post(new UninstallSilentRunnable(pkgname));
        else
            ht.post(new UninstallUnsilentRunnable(pkgname));
    }

    public int getApkPreferInstallLocation(String file) {
        int installlocation = 0;
        try {
            PackageParser.PackageLite pkg = null;
            if (VERSION.SDK_INT < 21) {
                Method staticMethod = PackageParser.class.getDeclaredMethod("parsePackageLite",
                        new Class[]{String.class, int.class});
                pkg = (PackageParser.PackageLite) staticMethod.invoke(null,
                        new Object[]{file, 0});
            } else {
                Method staticMethod = PackageParser.class.getDeclaredMethod("parsePackageLite",
                        new Class[]{File.class, int.class});
                pkg = (PackageParser.PackageLite) staticMethod.invoke(null, new Object[]{
                        new File(file), 0});
            }
            if (pkg != null)
                installlocation = pkg.installLocation;
            Runtime.getRuntime().gc();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return installlocation;
    }

    public AppInfo getAPKInfo(String apkfile) {
        try {
            AppInfo info = null;
            PackageInfo packageinfo = mContext.getPackageManager().getPackageArchiveInfo(apkfile,
                    PackageManager.GET_ACTIVITIES);
            if (packageinfo != null) {
                info = new AppInfo();
                ApplicationInfo appInfo = packageinfo.applicationInfo;
                info.apkPath = apkfile;
                try {
                    info.appName = mContext.getPackageManager().getApplicationLabel(appInfo)
                            .toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                info.pkgName = appInfo.packageName;
                info.versionName = packageinfo.versionName;
                info.versionCode = packageinfo.versionCode;
            }
            return info;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean isAppInstalled(String packageName) {
        PackageManager mPackageManager = mContext.getPackageManager();
//        Intent intent = mPackageManager.getLaunchIntentForPackage(packageName);
//        if (intent == null)
//            return false;
//        else
//            return true;
        PackageInfo info = null;
        try {
            info = mPackageManager.getPackageInfo(packageName, PackageManager.GET_DISABLED_COMPONENTS);
        } catch (NameNotFoundException e) {
//            e.printStackTrace();
            LogUtils.i(TAG, "isAppInstalled not installed!!  pkg:" + packageName + "  ");
            return false;
        }

        if (info != null)
            return true;
        else
            return false;
    }

    public int getInstallState(String pkgname) {
        if (isAppInstalled(pkgname))
            return PMUtils.INSTALL_STATE_INSTALLED;
        else {
            if (PackageRunnable.hasRunningPackage(pkgname))
                return PMUtils.INSTALL_STATE_INSTALLING;
            else
                return PMUtils.INSTALL_STATE_NO_INSTALL;
        }
    }

    public boolean startApp(String clsName,  boolean isRoot, String pkgname) {
        boolean ret = false;
        CoocaaApplication.CoocaaVersion coocaaversion = null;
        try {
            coocaaversion = CoocaaApplication.getCoocaaVersion();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (coocaaversion != null && coocaaversion.major >= 5) {
            try{
                Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(pkgname);
                HashMap<String,String> map = new HashMap<String,String>();
                map.put("pkgname", pkgname);
                SkyStartActivity.startActivity(mContext, clsName, intent, map, isRoot);
                ret = true;
            }catch (Exception e){
                e.printStackTrace();
            }
        } else {
            try {
                ret = XServiceManager.getLiteCCConnectorService().startAppWithPackageName(pkgname);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        if (ret) {
            Intent i = new Intent();
            i.setAction("com.coocaa.x.service.litecontent.startapp");
            i.putExtra("pkg", pkgname);
            mContext.sendBroadcast(i);
        }
        return ret;
    }

    public boolean startAppByComponentName(String clsName, boolean isRoot, ComponentName component) {
        boolean ret = false;
        CoocaaApplication.CoocaaVersion coocaaversion = null;
        try {
            coocaaversion = CoocaaApplication.getCoocaaVersion();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (coocaaversion != null && coocaaversion.major >= 5) {
            if(component.getClassName() != null && !component.getClassName().equals("")){
                Intent intent = new Intent();
                intent.setComponent(component);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                HashMap<String,String> map = new HashMap<String,String>();
                map.put("pkgname", component.getPackageName());
                SkyStartActivity.startActivity(mContext, clsName, intent, map, isRoot);
                ret = true;
            }else{
                ret = startApp(clsName,  isRoot, component.getPackageName());
            }
        } else {
            try {
                ret = XServiceManager.getLiteCCConnectorService().startAppWithComponentName(component);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                LogUtils.d(TAG, "start app  error!!");
                e.printStackTrace();
            } catch (Exception e) {
                LogUtils.d(TAG, "" + e);
            }
        }
        if (ret) {
            Intent i = new Intent();
            i.setAction("com.coocaa.x.service.litecontent.startapp");
            i.putExtra("pkg", component.getPackageName());
            mContext.sendBroadcast(i);
        }
        return ret;
    }

    public void movePackage(final String packageName, final PackageMoveLocation location,
                            final AppMoveListener listener) {
        PackageManager pm = mContext.getPackageManager();
        try {
            Method movepackage = pm.getClass().getMethod("movePackage", String.class,
                    IPackageMoveObserver.class, int.class);
            switch (location) {
                case EXTERNAL_MEDIA: {
                    final int flag = 0x00000002;
                    movepackage.invoke(pm, packageName, new IPackageMoveObserver.Stub() {
                        @Override
                        public void packageMoved(String arg0, int arg1) throws RemoteException {
                            // TODO Auto-generated method stub
                            if (listener != null) {
                                PackageMoveLocation location = getPackageInstalledLocation(arg0);
                                listener.onPackageMoved(arg0, location,
                                        PackageMoveLocation.EXTERNAL_MEDIA == location);
                            }
                        }
                    }, flag);
                    break;
                }
                case INTERNAL_MEMORY: {
                    final int flag = 0x00000001;
                    movepackage.invoke(pm, packageName, new IPackageMoveObserver.Stub() {
                        @Override
                        public void packageMoved(String arg0, int arg1) throws RemoteException {
                            // TODO Auto-generated method stub
                            if (listener != null) {
                                PackageMoveLocation location = getPackageInstalledLocation(arg0);
                                listener.onPackageMoved(arg0, location,
                                        PackageMoveLocation.INTERNAL_MEMORY == location);
                            }
                        }
                    }, flag);
                    break;
                }
                default:
                    break;
            }
        } catch (Exception e) {
            if (listener != null) {
                Logger.e("move package error " + e.toString());
                listener.onPackageMoved(packageName, getPackageInstalledLocation(packageName),
                        false);
            }
            e.printStackTrace();
        }
    }

    public void clearCache(final String pname, final AppClearCacheListener listener) {
        PackageManager pm = mContext.getPackageManager();
        try {
            Method deleteApplication = pm.getClass().getMethod("deleteApplicationCacheFiles",
                    String.class, IPackageDataObserver.class);
            deleteApplication.invoke(pm, pname, new IPackageDataObserver.Stub() {
                @Override
                public void onRemoveCompleted(String packageName, boolean succeeded)
                        throws RemoteException {
                    // TODO Auto-generated method stub
                    if (listener != null) {
                        listener.onPackageCacheClear(packageName, succeeded);
                    }
                }
            });
        } catch (Exception e) {
            if (listener != null) {
                listener.onPackageCacheClear(pname, false);
            }
            e.printStackTrace();
        }
    }

    private PackageMoveLocation getPackageInstalledLocation(String pname) {
        PackageManager pm = mContext.getPackageManager();
        ApplicationInfo appInfo;
        try {
            appInfo = pm.getApplicationInfo(pname, 0);
            if ((appInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
                return PackageMoveLocation.EXTERNAL_MEDIA;
            }
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return PackageMoveLocation.INTERNAL_MEMORY;
    }

    public synchronized void setSpeedUpListener(SpeedUpListener l) {
        speedUpListener = l;
    }

    public synchronized boolean speedUp(final int delay) {
        if (speedUpThread == null) {
            speedUpThread = new Thread("speedUpThread") {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        if (speedUpListener != null)
                            speedUpListener
                                    .onSpeedUpStart(delay, SystemUtils.getmem_UNUSED(mContext),
                                            SystemUtils.getmem_TOLAL());
                        SystemUtils.killAll(mContext);
                        if (speedUpListener != null)
                            speedUpListener
                                    .onSpeedUpReallyKillEnd(SystemUtils.getmem_UNUSED(mContext),
                                            SystemUtils.getmem_TOLAL());
                        Thread.sleep(delay);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        if (speedUpListener != null)
                            speedUpListener.onSpeedUpEnd();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    speedUpThread = null;
                }
            };
            speedUpThread.start();
            return true;
        }
        return false;
    }

    public synchronized void killProcess(String pname) {
        SkySystemUtil.killCurrentRunningPackage(mContext, pname);
    }

    public synchronized AppInfo getInstalledAppInfo(String pkgname) {
        PackageManager pm = mContext.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setPackage(pkgname);
        List<ResolveInfo> resolveInfo = pm.queryIntentActivities(intent, PackageManager.GET_DISABLED_COMPONENTS);
        // List<AppInfo> appList = new ArrayList<AppInfo>();
        if (resolveInfo != null && resolveInfo.size() > 0) {
            AppInfo appinfo = new AppInfo();
            ResolveInfo info = resolveInfo.get(0);
            List<MActivityInfo> list = new ArrayList<MActivityInfo>();
            if ((info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
                    || pkgname.equals("com.tianci.appstore"))
                appinfo.isSystemApp = true;
            appinfo.pkgName = info.activityInfo.packageName;
//            if (appinfo.pkgName.equals("com.tianci.localmedia"))
//                appinfo.appName = mContext.getString(R.string.local_media);   //"本地媒体";
//            else
//                appinfo.appName = info.loadLabel(mContext.getPackageManager()).toString();
            appinfo.mainActivity = info.activityInfo.name;
            for (ResolveInfo rInfo : resolveInfo) {
                MActivityInfo aInfo = new MActivityInfo();
                aInfo.pkg = rInfo.activityInfo.packageName;
                aInfo.className = rInfo.activityInfo.name;

                aInfo.name = rInfo.loadLabel(mContext.getPackageManager()).toString();
                list.add(aInfo);
            }

            if (appinfo.pkgName.equals("com.tianci.appstore")
                    && CoocaaApplication.getContentChannel().startsWith("Common")) {
                MActivityInfo aInfo = new MActivityInfo();
                aInfo.pkg = appinfo.pkgName;
                aInfo.className = "com.tianci.appstore.AppStoreActivity";
                aInfo.name = "应用圈";
                list.add(aInfo);
                MActivityInfo aInfo2 = new MActivityInfo();
                aInfo2.pkg = appinfo.pkgName;
                aInfo2.className = "com.coocaa.app.gamecenter.pages.home.GameMainActivity";
                aInfo2.name = "酷游吧";
                list.add(aInfo2);
            }

            appinfo.activityList = list;
            try {
                PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(
                        info.activityInfo.packageName, 0);
                if (appinfo.pkgName.equals("com.tianci.localmedia"))
                    appinfo.appName = mContext.getString(R.string.local_media);   //"本地媒体";
                else
                    appinfo.appName = packageInfo.applicationInfo.loadLabel(mContext.getPackageManager()).toString();
                appinfo.versionName = packageInfo.versionName;
                appinfo.versionCode = packageInfo.versionCode;
                appinfo.firstInstallTime = packageInfo.firstInstallTime;
                if (packageInfo.sharedUserId != null && packageInfo.sharedUserId.equals("android.uid.system")) {
                    appinfo.isSystemUserId = true;
                } else {
                    appinfo.isSystemUserId = false;
                }
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
            appinfo.size = new File(info.activityInfo.applicationInfo.publicSourceDir).length();

            return appinfo;
        }
        return new AppInfo();
    }

    public synchronized AppInfo getAppInfoFromLocal(String pkgname) {
        PackageManager pm = mContext.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
//        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setPackage(pkgname);
//        List<ResolveInfo> resolveInfo = pm.queryIntentActivities(intent, 0);
        List<ResolveInfo> resolveInfo = pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
        // List<AppInfo> appList = new ArrayList<AppInfo>();
        AppInfo appinfo = new AppInfo();
        if (resolveInfo != null && resolveInfo.size() > 0) {
            LogUtils.d(TAG, "getAppInfoFromLocal   pkg:" + pkgname);
            ResolveInfo info = resolveInfo.get(0);
            List<MActivityInfo> list = new ArrayList<MActivityInfo>();
            if ((info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
                    || pkgname.equals("com.tianci.appstore"))
                appinfo.isSystemApp = true;
            appinfo.pkgName = pkgname;
//            appinfo.appName = info.loadLabel(mContext.getPackageManager()).toString();
            appinfo.mainActivity = info.activityInfo.name;
            for (ResolveInfo rInfo : resolveInfo) {
                MActivityInfo aInfo = new MActivityInfo();
                aInfo.pkg = rInfo.activityInfo.packageName;
                aInfo.className = rInfo.activityInfo.name;

                aInfo.name = rInfo.loadLabel(mContext.getPackageManager()).toString();
                list.add(aInfo);
            }
            appinfo.activityList = list;
            try {
                PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(
                        info.activityInfo.packageName, 0);
                appinfo.appName = packageInfo.applicationInfo.loadLabel(mContext.getPackageManager()).toString();
                appinfo.versionName = packageInfo.versionName;
                appinfo.versionCode = packageInfo.versionCode;
                appinfo.firstInstallTime = packageInfo.firstInstallTime;
                if (packageInfo.sharedUserId != null && packageInfo.sharedUserId.equals("android.uid.system")) {
                    appinfo.isSystemUserId = true;
                } else {
                    appinfo.isSystemUserId = false;
                }
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            appinfo.size = new File(info.activityInfo.applicationInfo.publicSourceDir).length();

            return appinfo;
        }else{
            appinfo.pkgName = pkgname;
            appinfo.appName = "";
            return appinfo;
        }
    }

    public synchronized List<AppInfo> getInstalledAppList() {
        List<AppInfo> installedApps = new ArrayList<AppInfo>();
        LogUtils.d(TAG, "loadInstalledApps   installedApps.size:" + installedApps.size());
        List<ApplicationInfo> list = mContext.getPackageManager().getInstalledApplications(PackageManager.GET_DISABLED_COMPONENTS);
        for (ApplicationInfo app : list) {
            AppInfo info = getInstalledAppInfo(app.packageName);
            if (info != null && info.pkgName != null && !info.pkgName.equals(""))
                installedApps.add(info);
        }

        LogUtils.d(TAG, "loadInstalledApps  size:" + installedApps.size());
        return installedApps;
    }

    public synchronized void clearSpeedUpListener(SpeedUpListener l) {
        speedUpListener = null;
    }

    private int getConfigInstallLocation() {
        int ret = Settings.Secure.getInt(mContext.getContentResolver(), "default_install_location", 0);
        LogUtils.d("install", "settings getInstallLocation:" + ret);
//        if(ret == 0)
//            return 2;    //应酷开系统需求，如果location为自动（0），则当成外部（2）来处理。
        return ret;
        // 0：自动
        // 1：内部
        // 2：外部
    }

    private int getInstallLocation(String apk) {
//        int pos = getApkPreferInstallLocation(apk);
//        LogUtils.d("install",apk + "apk getInstallLocation:" + pos);
//        if (pos <= 0)
        int pos = getConfigInstallLocation();
        LogUtils.d("install", apk + "settings getInstallLocation:" + pos);
        return pos;
    }

    private boolean needInstallSystem(String apkPath) {
        PackageInfo pkgInfo = mContext.getPackageManager().getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
        LogUtils.d("install", "(pkgInfo != null):" + (pkgInfo != null));
        if (pkgInfo != null) {
            if (pkgInfo.sharedUserId != null && pkgInfo.sharedUserId.equals("android.uid.system")) {
                LogUtils.d("install", apkPath + "is system uid !");
                return true;
            }
            boolean isSystemApp = isSystemApp(pkgInfo.packageName);
            if (isSystemApp)
                return true;
            return false;
        }
        return false;
    }

    private boolean isSystemApp(String pkg) {
        PackageManager pm = mContext.getPackageManager();
        try {
            ApplicationInfo info = pm.getApplicationInfo(pkg, PackageManager.GET_DISABLED_COMPONENTS);
            LogUtils.d("install", " sourceDir:" + info.sourceDir);
            if (info.sourceDir.startsWith("/system") || info.sourceDir.startsWith("system"))
                return true;
            return false;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }


}
